Imports System.Data
Imports System.Data.SqlClient

'Namespace SVCMS.Library

<Serializable()> Public MustInherit Class DBTableObjectCollectionBase
    Inherits CollectionBase
    Implements IComparer
    Implements IList


#Region "Declarations"
    <NonSerialized()> Protected Friend iConnection As SqlClient.SqlConnection
    <NonSerialized()> Protected Friend iTransaction As SqlClient.SqlTransaction

    Protected Friend deletedList As New Collection
    Protected Friend iTableName As TableNamesEnum
    Protected Friend iLMUserId As Guid
    Protected Friend iLMDate As DateTime = DateTime.Now
    Protected Friend iRefId As Guid = Guid.Empty

    Protected Friend ipropertyToSort As String
    Protected Friend isortOrder As DBTOSortOrder
    Protected Friend isortExpresion As String
#End Region

#Region "Constructors"

    Private Sub New()
    End Sub

    Public Sub New(ByVal TableName As TableNamesEnum)
        Me.iTableName = TableName
    End Sub

    Public Sub New(ByVal TableName As TableNamesEnum, ByVal RefId As Guid)
        Me.iTableName = TableName
        Me.iRefId = RefId
    End Sub

#End Region

#Region "Properties"

    Friend ReadOnly Property TableName() As TableNamesEnum
        Get
            Return Me.iTableName
        End Get
    End Property

    Public Overridable Property RefId() As Guid
        Get
            Return Me.iRefId
        End Get
        Set(ByVal value As Guid)
            Me.iRefId = value
        End Set
    End Property

    Public Property LMUserId() As Guid
        Get
            Return Me.iLMUserId
        End Get
        Set(ByVal value As Guid)
            Me.iLMUserId = value
        End Set
    End Property

    Public Property LMDate() As DateTime
        Get
            Return Me.iLMDate
        End Get
        Set(ByVal value As DateTime)
            Me.iLMDate = value
        End Set
    End Property

    Friend Overridable Property Connection() As SqlConnection
        Get
            Return Me.iConnection
        End Get
        Set(ByVal value As SqlConnection)
            Me.iConnection = value
        End Set
    End Property

    Protected Friend Property Transaction() As SqlTransaction
        Get
            Return Me.iTransaction
        End Get
        Set(ByVal value As SqlTransaction)
            Me.iTransaction = value
        End Set
    End Property

#End Region

#Region "Procedures"

    Protected Friend MustOverride Function Load() As Boolean

    Protected NotOverridable Overrides Sub OnValidate(ByVal value As Object)
        If IsNothing(value) Then Exit Sub
        'If Not GetType(DBTableObjectBase).IsAssignableFrom(value.GetType()) Then
        '    Throw New ArgumentException("Value must be of type DBTableObjectBase")
        'End If
    End Sub

    Protected NotOverridable Overrides Sub OnInsert(ByVal index As Integer, ByVal value As Object)
        'CType(value, IDBTableObject).Changed = ChangeType.NewItem
        MyBase.OnInsert(index, value)
    End Sub

    Protected NotOverridable Overrides Sub OnRemove(ByVal index As Integer, ByVal value As Object)
        Me.deletedList.Add(value)
        MyBase.OnRemove(index, value)
    End Sub

    Protected NotOverridable Overrides Sub OnClear()
        Dim obj As DBTableObjectBase
        For Each obj In List
            Me.deletedList.Add(obj)
        Next
        MyBase.OnClear()
    End Sub

    Protected NotOverridable Overrides Sub OnSet(ByVal index As Integer, ByVal oldValue As Object, ByVal newValue As Object)
        MyBase.OnSet(index, oldValue, newValue)
    End Sub

    Protected Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.IComparer.Compare
        Try
            If Me.isortOrder = DBTOSortOrder.None Then Return 0
            If ipropertyToSort Is Nothing Then
                Dim xt As String = ""
                Dim yt As String = ""
                Dim tsections() As String = isortExpresion.Split(" ")
                For Each ts As String In tsections
                    If ts.StartsWith("/") Then
                        xt &= CallByName(x, ts.Substring(1), CallType.Get).ToString & " "
                        yt &= CallByName(y, ts.Substring(1), CallType.Get).ToString & " "
                    Else
                        xt &= ts & " "
                        yt &= ts & " "
                    End If
                Next
                If Me.isortOrder = DBTOSortOrder.Ascending Then
                    Return String.Compare(xt, yt, True)
                Else
                    Return String.Compare(xt, yt, True) * -1
                End If
            Else
                Dim prop As Reflection.PropertyInfo = x.GetType.GetProperty(Me.ipropertyToSort)

                If prop.GetValue(x, Nothing) = prop.GetValue(y, Nothing) Then
                    Return 0
                Else
                    Select Case prop.PropertyType.ToString
                        Case Is = "System.String"
                            If Me.isortOrder = DBTOSortOrder.Ascending Then
                                Return String.Compare(prop.GetValue(x, Nothing), prop.GetValue(y, Nothing), True)
                            Else
                                Return String.Compare(prop.GetValue(x, Nothing), prop.GetValue(y, Nothing), True) * -1
                            End If
                        Case Is = "System.Int16", "System.Int32", "System.Int64", "System.DateTime"
                            If prop.GetValue(x, Nothing) > prop.GetValue(y, Nothing) Then
                                If Me.isortOrder = DBTOSortOrder.Ascending Then Return 1 Else Return -1
                            Else
                                If Me.isortOrder = DBTOSortOrder.Ascending Then Return -1 Else Return 1
                            End If
                        Case Else
                            If prop.GetValue(x, Nothing).ToString > prop.GetValue(y, Nothing).ToString Then
                                If Me.isortOrder = DBTOSortOrder.Ascending Then Return 1 Else Return -1
                            Else
                                If Me.isortOrder = DBTOSortOrder.Ascending Then Return -1 Else Return 1
                            End If
                    End Select
                End If
            End If
        Catch
            Return 0
        End Try
    End Function

    Public Sub Sort(ByVal SortExpresion As String, ByVal sortOrder As DBTOSortOrder)
        isortOrder = sortOrder
        ipropertyToSort = Nothing
        isortExpresion = SortExpresion
        Me.InnerList.Sort(Me)
    End Sub

#End Region

#Region "Overloads/Overrides"

    Public Overridable Function IndexOf(ByVal value As DBTableObjectBase) As Integer
        Return Me.List.IndexOf(value)
    End Function

    Public Overridable Function Add(ByVal value As DBTableObjectBase) As Integer
        Return Me.List.Add(value)
    End Function

    Public Overridable Sub Insert(ByVal index As Integer, ByVal value As DBTableObjectBase)
        Me.List.Insert(index, value)
    End Sub

    Public Overridable Overloads Sub Remove(ByVal value As DBTableObjectBase)
        'Me.List.RemoveAt(List.IndexOf(value))
        Dim i As Integer = 0
        For i = 0 To Me.List.Count - 1
            If CType(Me.List.Item(i), DBTableObjectBase).iId = value.iId Then
                Me.List.RemoveAt(i)
                Exit For
            End If
        Next
    End Sub

    Public Overridable Function Contains(ByVal value As DBTableObjectBase) As Boolean
        Return Me.List.Contains(value)
    End Function

#End Region

#Region "Utlity Functions"

    Public Function IIf(ByVal expression As Boolean, ByVal truePart As Object, ByVal falsePart As Object) As Object
        If expression Then
            Return truePart
        Else
            Return falsePart
        End If
    End Function

#End Region

End Class

'End Namespace
